var Foundations = IMPORTS.foundations;
var Future      = Foundations.Control.Future;
var AjaxCall    = Foundations.Comms.AjaxCall;
var StringUtils = Foundations.StringUtils;
var FS = IMPORTS.require("fs");
//var JSONLIB         = Foundations.JSON;
var JSONLIB = IMPORTS.foundations.JSON;


//var CONFIG_FILE_NAME = '/media/internal/files/config.json';
var CONFIG_FILE_NAME = '/media/cryptofs/apps/usr/palm/services/com.hpit.cdc.pagetrans.service/athp_engine_config.json';
var CONFIG_FILE_DIR = '/media/cryptofs/apps/usr/palm/services/com.hpit.cdc.pagetrans.service/';
var TEST_FILE_NAME = '/media/internal/files/ResourceRequestList.htm';
var configObj = null;
 

// Find text between a start and end text
function find_delimited(search_str, start_str, end_str, in_index) {
    var found_txt = null;
    var j = -1;
    var i = search_str.indexOf(start_str, in_index);
    if (i>0) {
        j = search_str.indexOf(end_str, i+start_str.length);
        if (j>0) {
            found_txt = search_str.substring(i+start_str.length, j);
        }
    }
    return {result:found_txt,index: j};
}

/*
* only for flat json 1 layer
*/
function json2form(sourcejson){
var result_txt = "";
  for(var attr in sourcejson) {
      if(result_txt.length > 0 ) {
         result_txt = result_txt + "&" + attr + "=" + sourcejson[attr];
      }else{
         result_txt = attr + "=" + sourcejson[attr];
      }
  }
  //result_txt = StringUtils.escapeHTML(result_txt);
  logInfo(" json2form " + result_txt);
  return result_txt;
}


//get the url http response with params
function get_url_response(source_url, in_params, methods, in_future) {

   
    var options = { "bodyEncoding":"utf8"};
    
    //for test
    logInfo("source_url, methods " + source_url + "||||" +methods);
    
    if (methods == "get") {
        var future1 = AjaxCall.get(source_url, options);
        in_future.nest(future1).then(function(future) {
            if (future.result.status == 200) { // 200 = Success
                result_string = future.result.responseText;
                logInfo('Ajax get success ' + result_string);
                //future.result = result_string;
                future.result= result_string;
                //return result_string;
            }else if(future.result.status == 302){ //302= redirection (need authentication)
                //need to call login....
                logInfo('Ajax get fail 302 ' + JSON.stringify(future.result) );
                future.result = 'login';
                //return "login";
            }else if(1) {
                logInfo('Ajax get fail ' + JSON.stringify(future.result) );
                //future.result = 'failed with error code: ' + future.result.status;
                future.result = 'failed';
                return "failed";
            }
         });
     }else { //post for right now
        var future1 = AjaxCall.post(source_url+"?"+json2form(in_params),"". options);
        logInfo( source_url+"?"+json2form(in_params) );
        in_future.nest(future1).then(function(future) {
            if (future.result.status == 200) { // 200 = Success
                result_string = future.result.responseText;
                logInfo('Ajax post success ' );
                future.result= result_string;
                //return result_string;
            }else if(future.result.status == 302){ //302= redirection (need authentication)
                //need to call login....
                logInfo('Ajax post fail 302 ' + JSON.stringify(future) );
                future.result = 'login';
                //return "login";
            }else if(1) {
                logInfo('Ajax post fail ' + JSON.stringify(future.result) );
                future.result = 'failed';
                //return "failed";
            }
         });
     }
     //in_future.result = null;
}

/*
* to read the site configuration file
*/
function initiation(config_filename)
{
  //read configuration file and transform to json object
  try{
    configObj = JSON.parse(FS.readFileSync(CONFIG_FILE_DIR+config_filename, "utf8"));
  }catch(e) {
    logInfo('exception while reading configuration file ' +e);
  }
  return configObj;
}


/*
* call the page service
*/
function call_page_service(in_servicename, in_params, in_future)
{
  //get pagelist
  var page_list = configObj.page_list;
  //logInfo("in_servicename = " +in_servicename + "page_list =" + JSON.stringify(page_list));
  var result_json_string = "{";
  
  //get the required service information
  //var result = page_list. JSONLIB.query("\[?service_name=" +in_servicename +"\]", page_list);
  
  var result = null;
  var i = 0;
  
  while ( i < page_list.length && result == null ) {
    if (page_list[i].service_name == in_servicename ) {
        result = page_list[i];
    }else{
        i++;
    }  
  }//end of while
  
  var values = [];
 
  logInfo("servicename/result " + in_servicename+"/"+JSON.stringify(result));
  
  var response_content = null;
  
  if (result != null) { 
    //get link
    
    //call the web server, use in_future to control the flow
    var f = new Future();
    
    var params = result.params;
    for(var attr in in_params){//
        params[attr] = in_params[attr];
    }
    
    logInfo( "params = " + JSON.stringify(params) );
   
    
    get_url_response(result.page_url, params, result.methods, f);
    //this is only for test
    //get_file_response(TEST_FILE_NAME, f);
    
    //this is only for test
    //in_future.result = {reply: f.result};
    
    f.then( function(future) {
      if(future.result)  { //
    
            logInfo(" future.result " + JSON.stringify(future.result));
            response_content = future.result;
            
            //process the result
            //get the startposition
            var j = 0;
            var index_i = 0;
            
            //start process the content based on patterns in the configuration
            var patterns = result.patterns;
            
            logInfo("pring the patterns " + JSON.stringify(patterns));
                    
            for(j = 0; j < patterns.length; j++) {
              //process block firstly, if patterns.block != block, then don't need to process block function
              
              logInfo("pring the patterns[j] " + JSON.stringify(patterns[j]));
              
              if(patterns[j].block == "block") {
              
                //check whether it is a block information, if so, only process the block
                var temp_result = find_delimited(response_content, patterns[j].prefix_tag, patterns[j].suffix_tag, index_i);
                response_content = temp_result.result;
                index_i = temp_result.index;
                
                //updated index for changed response content,if it is valid
                if(response_content) index_i = 0;
              }//end of pattern.block
              
              //start process value set
              var pattern = patterns[j].value_set;
              
              var k = 0;// the index of pattern---------patterns[j].value_set
              var m = 0;// index of values
              
              //print test information
              logInfo("response_content :" + response_content);
              logInfo(" pattern information " + JSON.stringify(pattern));
                              
              
              while (index_i >= 0) {
              
                //get value
                var value = {};
                k = 0;//reset to zero to extract from start
                while ( k < pattern.length && index_i >= 0 ) {
                  var temp_result = find_delimited(response_content, pattern[k].prefix_tag, pattern[k].suffix_tag, index_i);
                  value[pattern[k].attribute_name] = temp_result.result;
                  index_i = temp_result.index;
                  k++;
                  
                  //for test
                  logInfo(" index_i,k,m and value " + index_i + "," + k + "," + m + " ||| " +  JSON.stringify(value) );
                }//end of while
                
                //valid value set if index_i >= 0
                if(index_i >=0) {
                  values[m] = value;
                  m++;
                }
                
                //if it is not a repeated block, then break
                if( patterns[j].is_repeat == 'no' )break;
                //for test
                logInfo(" index_i,k,m and values " + index_i + "," + k + "," + m + " ||| " +  JSON.stringify(values) );
                                                   
              }
              
              
            }//end of for(j=0
      }//end of if(future.result)
      
      in_future.result = {reply: values, 'hehe':'miaomiao'};
    }); //end of future          
              
  }else{ //not find requested service
    //return empty object
      in_future.result = {reply: values, 'hehe':'miaomiao'};
  }//end of if result
  

}



/*
* customized http call to get url response
*/
//function custom_get_url_response(source_url, in_params, methods, in_future)
//{

//    var headers = "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n"
//                  + "Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3\n"
//                  +"Accept-Encoding:gzip,deflate,sdch\n"
//                  +"Accept-Language:en-US,en;q=0.8\n"
//                  +"Connection:keep-alive\n";
//                  
//    //get port from source url

//    var temp_result = find_delimited(source_url, ":", "/", 6);
//    var port = temp_result.result;
//    var host_name = source_url.substring(0,j-port.length) + source_url.substring(j+1,source_url.length);
//    
//    logInfo(" url and port " + host_name + "  " + port);
//    
//    var client = http.createClient(port, host_name);
//    var request = client.request("POST", "/jsonrpc", headers);//instructions.headers);

//    client.on('error', function (e) {
//        future.result = {'responseText':JSON.stringify(error)};
//    });

//    var outbody = '';
//    
//    request.on('response', function (response) {
//        response.on('data', function (chunk) {
//        outbody += chunk;
//    });
//    response.on('end', function () {
//        logInfo(outbody);
//        in_future.result = {'responseText':outbody};
//    });
//    
//    request.write(instructions.body);
//    request.end();

//    return future;
//}



/*
* to process the content
*/
function process_content(content)
{
  logInfo(response);
  return response;
}

/*
* get html content from a file
*/

function get_file_response(filename, in_future)
{
   var content = file_read(filename).content;
   
   
   //for test purpose to generate escapted html
   //file_write('/media/internal/files/ResourceRequestList1.htm', StringUtils.escapeHTML(content));
   in_future.result = content;
   
}

/*
*  read a dir and get list of files
*/

function dir_read(dirname)
{
   return { files: FS.readdirSync(filename) };
}

/*
*  read a file
*/

function file_read(filename)
{
   return { name: filename, content: FS.readFileSync(filename, 'utf8') };
}

/*
*  write a file
*/

function file_write(filename, filecontent)
{
   return { name: filename, bytes: FS.writeFileSync(filename, filecontent, 'utf8') };
}


